{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 多策略, 多品种回测示例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from collections import defaultdict\n",
    "\n",
    "import OnePy as op\n",
    "from OnePy.custom_module.cleaner_talib import Talib\n",
    "from OnePy.custom_module.cleaner_sma import SMA\n",
    "\n",
    "class SmaStrategy(op.StrategyBase):\n",
    "\n",
    "    def __init__(self):\n",
    "\n",
    "        super().__init__()\n",
    "        self.sma1 = SMA(3, 40).calculate\n",
    "        self.sma2 = SMA(5, 40).calculate\n",
    "\n",
    "    def handle_bar(self):\n",
    "        for ticker in self.env.tickers:\n",
    "\n",
    "            if self.sma1(ticker) > self.sma2(ticker):\n",
    "\n",
    "                self.buy(100, ticker, takeprofit=15,\n",
    "                         stoploss=100)\n",
    "            else:\n",
    "                self.sell(20, ticker)\n",
    "\n",
    "class BBANDS(op.StrategyBase):\n",
    "\n",
    "    def __init__(self):\n",
    "        super().__init__()\n",
    "        self.sma = Talib(ind='sma', frequency='D',\n",
    "                         params=dict(timeperiod=20)).calculate\n",
    "\n",
    "        self.bbands = Talib(ind='BBANDS', frequency='D',\n",
    "                            params=dict(timeperiod=20,\n",
    "                                        nbdevup=2,\n",
    "                                        nbdevdn=2,\n",
    "                                        matype=0),\n",
    "                            buffer_day=30).calculate\n",
    "\n",
    "        self.switch_long = defaultdict(bool)\n",
    "        self.switch_short = defaultdict(bool)\n",
    "\n",
    "        self.params = dict(\n",
    "            position=100,\n",
    "            takeprofit_pct=0.01,\n",
    "        )\n",
    "        self.finished = defaultdict(list)\n",
    "\n",
    "    def handle_bar(self):\n",
    "        position = self.params['position']\n",
    "        takeprofit_pct = self.params['takeprofit_pct']\n",
    "\n",
    "        for ticker in self.env.tickers:\n",
    "            upperband = self.bbands(ticker)['upperband']\n",
    "            middleband = self.bbands(ticker)['middleband']\n",
    "            lowerband = self.bbands(ticker)['lowerband']\n",
    "            cur_price = self.cur_price(ticker)\n",
    "            sma = self.sma(ticker)\n",
    "\n",
    "            if cur_price > upperband > sma:\n",
    "                if ticker not in self.finished['long']:\n",
    "                    self.buy(position, ticker, price=cur_price -\n",
    "                             0.01, trailingstop_pct=0.05)\n",
    "                    self.finished['long'].append(ticker)\n",
    "\n",
    "            elif cur_price < lowerband < sma:\n",
    "                if ticker not in self.finished['short']:\n",
    "                    self.short(position, ticker, price=cur_price +\n",
    "                               0.01, trailingstop_pct=0.05)\n",
    "                    self.finished['short'].append(ticker)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "+--------------------+\n",
      "|readers_1  |  000001|\n",
      "|readers_2  |  000002|\n",
      "+--------------------+\n",
      "+----------------------+\n",
      "|cleaners_1  |    SMA_1|\n",
      "|cleaners_2  |    SMA_2|\n",
      "|cleaners_3  |  Talib_3|\n",
      "|cleaners_4  |  Talib_4|\n",
      "+----------------------+\n",
      "+--------------------------+\n",
      "|strategy_1  |  SmaStrategy|\n",
      "|strategy_2  |       BBANDS|\n",
      "+--------------------------+\n",
      "+-------------------------+\n",
      "|brokers_1  |  StockBroker|\n",
      "+-------------------------+\n",
      "+-----------------------------------------------+\n",
      "|risk_managers_1  |  StockLimitFilterRiskManager|\n",
      "+-----------------------------------------------+\n",
      "+-----------------------------+\n",
      "|recorders_1  |  StockRecorder|\n",
      "+-----------------------------+\n"
     ]
    }
   ],
   "source": [
    "TICKER_LIST = ['000001', '000002'] # 多品种\n",
    "INITIAL_CASH = 20000\n",
    "FREQUENCY = 'D'\n",
    "START, END = '2012-08-07', '2018-08-07'\n",
    "\n",
    "go = op.backtest.stock(TICKER_LIST, FREQUENCY, INITIAL_CASH, START, END)\n",
    "\n",
    "# 导入多个策略\n",
    "SmaStrategy() \n",
    "BBANDS() \n",
    "\n",
    "go.output.show_setting() # 检查是否导入成功"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "正在初始化OnePy\n",
      "Retry Talib_3, perfect buffer_day = 29\n",
      "Retry Talib_3, perfect buffer_day = 27\n",
      "Retry Talib_3, perfect buffer_day = 25\n",
      "Retry Talib_3, perfect buffer_day = 23\n",
      "Retry Talib_3, perfect buffer_day = 21\n",
      "Retry Talib_3, perfect buffer_day = 19\n",
      "Retry Talib_3, perfect buffer_day = 17\n",
      "Retry Talib_3, perfect buffer_day = 15\n",
      "Retry Talib_3, perfect buffer_day = 13\n",
      "Retry Talib_3, perfect buffer_day = 11\n",
      "Retry Talib_3, perfect buffer_day = 9\n",
      "Retry Talib_3, perfect buffer_day = 7\n",
      "=============== OnePy初始化成功！ ===============\n",
      "开始寻找OnePiece之旅~~~\n",
      "Cash is not enough for trading!\n",
      "Cash is not enough for trading!\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "+--------------------------------+\n",
      "|Fromdate           |  2012-08-07|\n",
      "|Todate             |  2018-08-07|\n",
      "|Initial_Value      |   $20000.00|\n",
      "|Final_Value        |   $18241.37|\n",
      "|Total_Return       |     -8.793%|\n",
      "|Max_Drawdown       |     12.887%|\n",
      "|Max_Duration       |    916 days|\n",
      "|Max_Drawdown_Date  |  2018-07-20|\n",
      "|Sharpe_Ratio       |       -0.26|\n",
      "+--------------------------------+\n"
     ]
    }
   ],
   "source": [
    "go.sunny()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "+---------------------------------------+\n",
      "|Start_date                |  2012-08-07|\n",
      "|End_date                  |  2018-08-07|\n",
      "|Initial_balance           |   $20000.00|\n",
      "|End_balance               |   $18241.37|\n",
      "|Total_return              |      -8.79%|\n",
      "|Total_net_pnl             |   -$1758.63|\n",
      "|Total_commission          |    $2527.56|\n",
      "|Total_trading_days        |   1566 days|\n",
      "|Max_drawdown              |      12.89%|\n",
      "|Max_drawdown_date         |  2018-07-20|\n",
      "|Max_duration_in_drawdown  |    916 days|\n",
      "|Max_margin                |      $69.57|\n",
      "|Max_win_holding_pnl       |     $104.54|\n",
      "|Max_loss_holding_pnl      |    -$661.70|\n",
      "|Sharpe_ratio              |       -0.26|\n",
      "|Sortino_ratio             |       -0.33|\n",
      "|Number_of_trades          |        2211|\n",
      "|Number_of_daily_trades    |        1.41|\n",
      "|Number_of_profit_days     |   1566 days|\n",
      "|Number_of_loss_days       |      0 days|\n",
      "|Avg_daily_pnl             |      -$1.12|\n",
      "|Avg_daily_commission      |       $1.61|\n",
      "|Avg_daily_return          |      -0.01%|\n",
      "|Avg_daily_std             |      -0.01%|\n",
      "|Annual_compound_return    |      -1.47%|\n",
      "|Annual_average_return     |      -1.48%|\n",
      "|Annual_std                |      -0.08%|\n",
      "|Annual_pnl                |    -$283.00|\n",
      "+---------------------------------------+\n",
      "                                All Trades  Long Trades Short Trades\n",
      "Total_number_of_trades                2211         2209            2\n",
      "Total_net_pnl                    -$1758.63    -$1742.93      -$15.70\n",
      "Ratio_avg_win_avg_loss                0.96         0.96         0.43\n",
      "Profit_factor                         1.05         1.05         0.43\n",
      "Percent_profitable                  52.01%       52.01%       50.00%\n",
      "Number_of_winning_trades              1150         1149            1\n",
      "Number_of_losing_trades               1057         1056            1\n",
      "Max_holding_period             199.62 days  199.62 days   20.62 days\n",
      "Max_consecutive_winning_trade           30           30            1\n",
      "Max_consecutive_losing_trade            32           32            0\n",
      "Largest_winning_trade               $15.00       $15.00       $10.51\n",
      "Largest_losing_trade              -$100.00     -$100.00      -$24.35\n",
      "Gross_profit                     $16623.41    $16612.90       $10.51\n",
      "Gross_loss                      -$15854.48   -$15830.14      -$24.35\n",
      "Gross_commission                  $2527.56     $2525.69        $1.87\n",
      "Expectancy_adjusted_ratio             0.02         0.02        -0.28\n",
      "Expectancy                           $0.32        $0.33       -$6.92\n",
      "Avg_winning_trade                   $14.46       $14.46       $10.51\n",
      "Avg_net_pnl_per_trade               -$0.80       -$0.79       -$7.85\n",
      "Avg_losing_trade                   -$15.00      -$14.99      -$24.35\n",
      "Avg_holding_period              13.08 days   13.08 days   11.12 days\n"
     ]
    }
   ],
   "source": [
    "go.output.summary2()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
